package com.css.fxfzdzzh.common.utils;

import com.css.fxfzdzzh.common.utils.cluster.Bounds;
import com.css.fxfzdzzh.common.utils.cluster.Point;
import com.linuxense.javadbf.DBFReader;
import org.apache.commons.lang3.StringUtils;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.WKTReader;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;

public class VectorDataUtil {

    private static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
    private static WKTReader reader = new WKTReader(geometryFactory);

    public static String readPRJ(String path) {
        StringBuffer result = new StringBuffer();
        File file = new File(path);
        if (!file.exists()) return "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                result.append(tempString);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }


    /*********************************DBF*************************************/

    public static String[] getFieldName(String path, String charsetName){
        try {
            DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
            int fieldCount = dbfReader.getFieldCount();//获取字段数量
            String[] fieldName = new String[fieldCount];
            for (int i = 0; i < fieldCount; i++) {
                fieldName[i] = dbfReader.getField(i).getName();
            }
            dbfReader.close();
            return fieldName;
        }catch(IOException ex){

        }
        return null;
    }

    /*
    public static String[] getFieldName(String path, String charsetName) throws IOException {
        DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
        int fieldCount = dbfReader.getFieldCount();//获取字段数量
        String[] fieldName = new String[fieldCount];
        for (int i = 0; i < fieldCount; i++) {
            fieldName[i] = dbfReader.getField(i).getName();
        }
        dbfReader.close();
        return fieldName;
    }

     */

    public static ArrayList<Object[]> getFieldValue(String path, String charsetName) throws IOException {
        ArrayList<Object[]> result = new ArrayList<Object[]>();
        DBFReader dbfReader = new DBFReader(new FileInputStream(path), Charset.forName(charsetName));
        Object[] rowValues;
        while ((rowValues = dbfReader.nextRecord()) != null) {
            result.add(rowValues);
        }
        dbfReader.close();
        return result;
    }

    public static SimpleFeatureCollection readDBF(String path) {
        return readShp(path, null);
    }

    public static SimpleFeatureCollection readDBF(String path, Filter filter) {
        SimpleFeatureSource featureSource = readStoreByDBF(path);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static SimpleFeatureSource readStoreByDBF(String path) {
        File file = new File(path);
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName("GBK"));
            featureSource = store.getFeatureSource();
            store.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return featureSource;
    }

    /*********************************DBF*********END****************************/


    /*********************************SHP*************************************/

    /*public static List<List<Object>> readSHPFile(String path, String codeType) {
        String prjPath = path.substring(0, path.length() - 4) + ".prj";
        String strWKTMercator = readPRJ(prjPath);
        if (strWKTMercator != "") ProjectTransUtil.setStrWKTMercator(strWKTMercator);
        String lonLatStr = "", wkt = "";
        SimpleFeatureCollection colls1 = readShp(path, codeType);
        SimpleFeatureIterator iters = colls1.features();
        String resMsg = "校验成功";
        int count = 0;
        double lon = 0, lat = 0;
        Map<Double, List<Double>> lon2latitudes = new HashMap<>();
        Map<Double, List<Double>> lat2longitudes = new HashMap<>();
        SimpleFeature sf = null;
        List<List<Object>> result = new ArrayList<List<Object>>();
        HashMap<Integer, List<Object>> list = new HashMap<Integer, List<Object>>();
        //zyt-test
        boolean tempBool = true;//判断是否需要转换经纬度值
        while (iters.hasNext()) {
            if(count%100000==0){
                System.out.println(count);
            }
            sf = iters.next();
            List<Object> attributes = sf.getAttributes();
            if(tempBool){
                wkt = attributes.get(0).toString();
                if (wkt.indexOf("MULTIPOINT") != -1) {
                    lonLatStr = reverseWktMultiPoint(ProjectTransUtil.wkt2lonLat(wkt));
                } else if (wkt.indexOf("POINT") != -1) {
                    lonLatStr = reverseWktPoint(ProjectTransUtil.wkt2lonLat(wkt));

                } else if (wkt.indexOf("MULTIPOLYGON") != -1) {
                    lonLatStr = reverseWktMultiPolygon(ProjectTransUtil.wkt2lonLat(wkt));
                } else if (wkt.indexOf("POLYGON") != -1) {
                    lonLatStr = reverseWktPolygon(ProjectTransUtil.wkt2lonLat(wkt));
                }
                attributes.set(0, lonLatStr);
                //判断是否经纬度值是否相等
                if(wkt.equals(lonLatStr)){
                    tempBool = false;//判断是否需要转换经纬度值
                }
            }
            *//*result.add(attributes);*//*
            //1.校验GeometryIsNotEqualsCoordinate
            String pointWkt = attributes.get(0).toString();
            String A = attributes.get(1).toString();
            String B = attributes.get(2).toString();
            if (!geometryIsEqualsCoordinate(pointWkt, A, B)) {
                resMsg = "GeometryIsNotEqualsCoordinate";
                System.out.println("GeometryIsNotEqualsCoordinate");
                break;
            }
            //2.校验是否有乱码
            int msssyIndex = -1;
            //校验是否有乱码
            for (int j = 0; j < attributes.size(); j++) {
                if(attributes.get(j)==null){
                    continue;
                }
                String value = attributes.get(j).toString();
                for (int k = 0; k < value.length() / 2; k++) {
                    char c = value.charAt(k);
                    // 当从Unicode编码向某个字符集转换时，如果在该字符集中没有对应的编码，则得到0x3f（即问号字符?）
                    //从其他字符集向Unicode编码转换时，如果这个二进制数在该字符集中没有标识任何的字符，则得到的结果是0xfffd
                    if ((int) c == 0xfffd) {
                        // 存在乱码
                        msssyIndex = count;
                        break;
                    }
                }
                if(msssyIndex!=-1){
                    resMsg = "msssyIndex"+msssyIndex;
                    System.out.println("msssyIndex"+msssyIndex);
                    break;
                }
            }
            if(msssyIndex!=-1){
                break;
            }
            //3.校验字段空值
            for (int j = 0; j < attributes.size(); j++) {
                if(attributes.get(j)==null){
                    resMsg = "fieldNullValue";
                    break;
                }
                String value = attributes.get(j).toString();
                //校验字段空值
                if (value == null || "".equals(value.trim())){
                    resMsg = "fieldNullValue";
                    System.out.println("fieldNullValue");
                    break;
                }
            }
            if(!resMsg.equals("校验成功")){
                break;
            }
            //4.校验空间分辨率不是6秒
            lon = Double.parseDouble(A);
            lat = Double.parseDouble(B);
            if (lon2latitudes.containsKey(lon)) {
                lon2latitudes.get(lon).add(lat);
            } else {
                List<Double> latitudes = new ArrayList<>();
                latitudes.add(lat);
                lon2latitudes.put(lon, latitudes);
            }
            if (lat2longitudes.containsKey(lat)) {
                lat2longitudes.get(lat).add(lon);
            } else {
                List<Double> longitudes = new ArrayList<>();
                longitudes.add(lon);
                lat2longitudes.put(lat, longitudes);
            }

            count++;
        }
        iters.close();

        System.out.println(count);

        //校验空间分辨率不是6秒
        if (!(isLessSixSecond(lon2latitudes) || isLessSixSecond(lat2longitudes))){
            resMsg = "SpatialResolutionError";
            System.out.println("SpatialResolutionError");
        }

        return result;
    }*/

    public static SimpleFeatureCollection readShp(String path, String codeType) {
        return readShp(path, null, codeType);
    }

    public static SimpleFeatureCollection readShp(String path, Filter filter, String codeType) {
        SimpleFeatureSource featureSource = readStoreByShp(path, codeType);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static SimpleFeatureSource readStoreByShp(String path, String codeType) {
        File file = new File(path);
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName(codeType));
            featureSource = store.getFeatureSource();
            store.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureSource;
    }
    /*********************************SHP*********END****************************/




    public static int judgeIsHaveMsssyCode(List<List<Object>> list) {
        /*String str = "";
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            for (int j = 0; j < values.size(); j++) {
                str = values.get(j).toString();
                if (isHaveMsssyCode(str)) return i;
            }
        }
        return -1;*/

        //zyt修改
        int msssyIndex = -1;
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            for (int j = 0; j < values.size(); j++) {
                String str = values.get(j).toString();
                if (VectorDataUtil.isHaveMsssyCode(str)){
                    msssyIndex = i;
                    break;
                }
            }
            if(msssyIndex!=-1){
                break;
            }
        }

        return msssyIndex;
    }
    private static boolean isHaveMsssyCode(String str) {
        for (int i = 0; i < str.length() / 2; i++) {
                /*if(=="#"){
                    continue;
                }*/
            char c = str.charAt(i);
            // 当从Unicode编码向某个字符集转换时，如果在该字符集中没有对应的编码，则得到0x3f（即问号字符?）
            //从其他字符集向Unicode编码转换时，如果这个二进制数在该字符集中没有标识任何的字符，则得到的结果是0xfffd
            if ((int) c == 0xfffd) {
                // 存在乱码
                return true;
            }
        }
        return false;
    }

    //校验经纬度
    public static boolean checkLonLat(List<List<Object>> list) {
        Bounds bounds = new Bounds(new Point(-180, -90), new Point(180, 90));
        Point point = null, _point = null;
        float firstValue = 0;
        String wkt = "", A = "", B = "";
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            wkt = values.get(0).toString();
            A = values.get(1).toString();
            B = values.get(2).toString();
            if (wkt.indexOf("MULTIPOINT") != -1) {
                wkt = wkt.substring(wkt.indexOf("(") + 2, wkt.lastIndexOf(")") - 1);
                String[] coords = wkt.split(" ");
                point = new Point(Float.parseFloat(coords[0]), Float.parseFloat(coords[1]));
            } else if (wkt.indexOf("POINT") != -1) {
                wkt = wkt.substring(wkt.indexOf("(") + 1, wkt.lastIndexOf(")") - 1);
                String[] coords = wkt.split(" ");
                point = new Point(Float.parseFloat(coords[0]), Float.parseFloat(coords[1]));
            } else {
                firstValue = Float.parseFloat(values.get(1).toString());
                point = new Point(firstValue, firstValue);
            }
            _point = new Point(Float.parseFloat(A), Float.parseFloat(B));
            if (!(bounds.containsPoint(point)) || !(bounds.containsPoint(_point))) return false;
        }
        return true;
    }


    public static boolean checkCGCS2000(String path) {
        String prjPath = path.substring(0, path.length() - 4) + ".prj";
        String strWKTMercator = readPRJ(prjPath);
        if (strWKTMercator == "") return false;
        CoordinateReferenceSystem sourceTarget = null;
        try {
            sourceTarget = CRS.parseWKT(strWKTMercator);
        } catch (FactoryException e) {
            e.printStackTrace();
            System.out.println(path + ": 解析错误!");
        }
        String name = sourceTarget.getName().toString();
        if (name.indexOf("CGCS2000") != -1 || name.indexOf("cgcs2000") != -1 || name.indexOf("Geodetic_Coordinate_System_2000") != -1 ||
                name.indexOf("Geodetic Coordinate System 2000") != -1) return true;
        return false;
    }

    //是否为罗马数字
    public static boolean checkLevel(List<List<Object>> list, String type) {
        String roman = "Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ", arab = "1 2 3 4", level = "";
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            if ("point".equals(type)) {
                level = values.get(3).toString();
                if (arab.indexOf(level) == -1) return false;
            } else if ("polygon".equals(type)) {
                level = values.get(1).toString();
                if (arab.indexOf(level) == -1) return false;
            } else if ("site".equals(type)) {
                level = transUsaClassi(values.get(1).toString());
                if (roman.indexOf(level) == -1) return false;
            }
        }
        return true;
    }
    public static String transUsaClassi(String usaClassi) {
        //zyt修改
        //Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ 水体 I0
        if ("1".equals(usaClassi)) {
            return "Ⅰ";
        } else if ("2".equals(usaClassi)) {
            return "Ⅱ";
        } else if ("3".equals(usaClassi)) {
            return "Ⅲ";
        } else if ("4".equals(usaClassi)) {
            return "Ⅳ";
        } else if ("9".equals(usaClassi)) {
            return "水体";
        } else if ("10".equals(usaClassi)) {
            return "Ⅰ0";
        }
        return usaClassi;

        /*String constant = "12345";//Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ
        if (constant.indexOf(usaClassi) != -1) {
            if ("1".equals(usaClassi)) {
                return "Ⅰ";
            } else if ("2".equals(usaClassi)) {
                return "Ⅱ";
            } else if ("3".equals(usaClassi)) {
                return "Ⅲ";
            } else if ("4".equals(usaClassi)) {
                return "Ⅳ";
            } else if ("5".equals(usaClassi)) {
                return "Ⅴ";
            }
        }
        return usaClassi;*/
    }

    //校验字段空值
    public static boolean checkValueIsBlank(List<List<Object>> list) {
        String value = "";
        for (int i = 0; i < list.size(); i++) {
            List<Object> attributes = list.get(i);
            for (int j = 0; j < attributes.size(); j++) {
                value = attributes.get(j).toString();
                if (value == null || "".equals(value.trim())) return false;
            }
        }
        return true;
    }

    /*public static boolean checkPointIsInDistrict(List<List<Object>> list, String province, String city, String area, String type) {

        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries = AreaBoundaryUtil.readSingleDistrictBoundary(province, city, area);

        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = null;
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] boundary = null;

        if ("point".equals(type)) {
            String longitude = "", latitude = "";
            for (int i = 0; i < list.size(); i++) {
                List<Object> attributes = list.get(i);
                longitude = attributes.get(1).toString();
                latitude = attributes.get(2).toString();
                point = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point(Double.parseDouble(longitude), Double.parseDouble(latitude));
                for (int j = 0; j < boundaries.size(); j++) {
                    boundary = boundaries.get(j);
                    if (!AreaBoundaryUtil.isPointInPolygon(point, boundary)) return false;
                }
            }
        } else if ("polygon".equals(type)) {
            String coordinates = "";
            for (int i = 0; i < list.size(); i++) {
                List<Object> attributes = list.get(i);
                coordinates = attributes.get(0).toString();
                coordinates = coordinates.toLowerCase();
                if (coordinates.indexOf("multipolygon") != -1) {
                    coordinates = coordinates.substring(coordinates.indexOf("(((") + 3, coordinates.lastIndexOf(")))"));
                    coordinates = coordinates.replace(")), ((", "|");
                    coordinates = coordinates.replace("), (", "#");
                } else if (coordinates.indexOf("polygon") != -1) {
                    String sp = coordinates.indexOf("),(") != -1 ? "),(" : (coordinates.indexOf("), (") != -1 ? "), (" : "");
                    String oldWkt = coordinates, coordinate = "";
                    if ("".equals(sp)) {
                        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 2, oldWkt.lastIndexOf("))"));
                        String[] _coordinates = oldWkt.split(",");
                        for (int j = 0; j < _coordinates.length; j++) {
                            String[] _coords = _coordinates[j].split(" ");
                            coordinate += _coords[0] + " " + _coords[1] + ",";
                        }
                        coordinate = coordinate.substring(0, coordinate.length() - 1);
                        coordinates = coordinate;
                    } else {
                        oldWkt = oldWkt.replace(sp, "#"); sp = "#";
                        String[] _coordinates = oldWkt.split(sp); String tempCoordinate = "";
                        for (int j = 0; j < _coordinates.length; j++) {
                            tempCoordinate = _coordinates[j];
                            String[] _coords = tempCoordinate.split(","), __coords = null;
                            for (int k = 0; k < _coords.length; k++) {
                                __coords = _coords[k].split(" ");
                                coordinate += __coords[0] + " " + __coords[1] + ",";
                            }
                            coordinate += coordinate.substring(0, coordinate.length() - 1) + "|";
                        }
                        coordinates = coordinate;
                    }
                }
                String[] geometries = StringUtils.split(coordinates, "|");
                for (int j = 0; j < geometries.length; j++) {
                    String geometry = geometries[j];
                    String[] subGeometries = StringUtils.split(geometry, "#");
                    for (int k = 0; k < subGeometries.length; k++) {
                        String subGeometry = subGeometries[k];
                        String[] lonLats = subGeometry.split(", ");
                        for (int l = 0; l < lonLats.length; l++) {
                            String[] lonLat = StringUtils.split(lonLats[l], " ");
                            point = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point(Double.parseDouble(lonLat[0]), Double.parseDouble(lonLat[1]));
                            for (int m = 0; m < boundaries.size(); m++) {
                                boundary = boundaries.get(m);
                                if (!AreaBoundaryUtil.isPointInPolygon(point, boundary)) return false;
                            }
                        }
                    }
                }
            }
        }

        return true;
    }*/

    public static String reverseWktMultiPolygon(String wktPolygon) {
        /*String oldWkt = wktPolygon;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(((") + 3, oldWkt.lastIndexOf(")))"));
        oldWkt = oldWkt.replace(")), ((", "|");
        oldWkt = oldWkt.replace("), (", "#");

        String wktPolygon1 = "(";
        String[] polygon1 = StringUtils.split (oldWkt, "|");
        for (int i = 0; i < polygon1.length; i++) {
            String[] polygon2 = StringUtils.split (polygon1[i], "#");
            for (int j = 0; j < polygon2.length; j++) {
                String wktPolygon2 = "(";
                String[] coords = polygon2[j].split(", ");
                for (int k = 0; k < coords.length; k++) {
                    String[] lonLat = coords[k].split(" ");
                    String lon = lonLat[1];
                    String lat = lonLat[0];
                    wktPolygon2 += lon + " " + lat + ", ";
                }
                wktPolygon2 = wktPolygon2.substring(0, wktPolygon2.length() - 2) + "), ";
                wktPolygon1 += wktPolygon2;
            }
            wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 2) + "), ";
        }
        wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 2);
        return "MULTIPOLYGON (" + wktPolygon1 + ")";*/

        //zyt
        String oldWkt = wktPolygon;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(((") + 3, oldWkt.lastIndexOf(")))"));
        oldWkt = oldWkt.replace(")), ((", "|");
        oldWkt = oldWkt.replace("), (", "#");

        String wktPolygon1 = "";
        String[] polygon1 = StringUtils.split (oldWkt, "|");
        for (int i = 0; i < polygon1.length; i++) {
            if(polygon1[i].indexOf("#")!=-1){
                String[] polygon2 = StringUtils.split(polygon1[i], "#");
                for (int j = 0; j < polygon2.length; j++) {
                    String wktPolygon2 = "";
                    String[] coords = polygon2[j].split(", ");
                    for (int k = 0; k < coords.length; k++) {
                        String[] lonLat = coords[k].split(" ");
                        String lon = lonLat[1];
                        String lat = lonLat[0];
                        wktPolygon2 += lon + " " + lat + ", ";
                    }
                    wktPolygon1 += wktPolygon2.substring(0, wktPolygon2.length() - 2) + "), (";
                }
                wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 4) + ")), ((";
            }else{
                String wktPolygon2 = "";
                String[] coords = polygon1[i].split(", ");
                for (int k = 0; k < coords.length; k++) {
                    String[] lonLat = coords[k].split(" ");
                    String lon = lonLat[1];
                    String lat = lonLat[0];
                    wktPolygon2 += lon + " " + lat + ", ";
                }
                wktPolygon1 += wktPolygon2.substring(0, wktPolygon2.length() - 2) + ")), ((";
            }
        }
        wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 6);

        return "MULTIPOLYGON (((" + wktPolygon1 + ")))";
    }

    public static String reverseWktPolygon(String wktPolygon) {
        String oldWkt = wktPolygon;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 2, oldWkt.lastIndexOf("))"));

        String polygonWkt = "Polygon (", coordinate = "";
        String sp = oldWkt.indexOf("),(") != -1 ? "),(" : (oldWkt.indexOf("), (") != -1 ? "), (" : "");
        if ("".equals(sp)) {
            coordinate = "(";
            String[] coordinates = oldWkt.split(",");
            for (int i = 0; i < coordinates.length; i++) {
                String[] coords = coordinates[i].split(" ");
                coordinate += coords[1] + " " + coords[0] + ",";
            }
            coordinate = coordinate.substring(0, coordinate.length() - 1) + ")";
            polygonWkt += coordinate + ")";
        } else {
            oldWkt = oldWkt.replace(sp, "#"); sp = "#";
            String[] coordinates = oldWkt.split(sp);
            for (int i = 0; i < coordinates.length; i++) {
                coordinate = coordinates[i];
                String _coordinates = "(";
                String[] coords = coordinate.split(","), _coords = null;
                for (int j = 0; j < coords.length; j++) {
                    _coords = coords[j].split(" ");
                    _coordinates += _coords[1] + " " + _coords[0] + ",";
                }
                _coordinates = _coordinates.substring(0, _coordinates.length() - 1) + ")";
                polygonWkt += _coordinates + ",";
            }
            polygonWkt += polygonWkt.substring(0, polygonWkt.length() - 1) + ")";
        }
        return polygonWkt;
    }

    public static String reverseWktPoint(String wktPoint) {
        String oldWkt = wktPoint;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 1, oldWkt.lastIndexOf(")"));
        String[] coords = oldWkt.split(" ");
        return "POINT (" + coords[1] + " " + coords[0] + ")";
    }

    public static String reverseWktMultiPoint(String wktMultiPoint) {
        String oldWkt = wktMultiPoint;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 2, oldWkt.lastIndexOf(")") - 1);
        String sp = oldWkt.indexOf("),(") != -1 ? "),(" : (oldWkt.indexOf("), (") != -1 ? "), (" : "");
        String[] coordinates = StringUtils.split(oldWkt, sp);
        String newWkt = "MULTIPOINT ((", coordinate = "";
        String[] coords = null;
        for (int i = 0; i < coordinates.length; i++) {
            coordinate = coordinates[i];
            coords = coordinate.split(" ");
            //newWkt += "(" + coords[1] + " " + coords[0] + "),";
            newWkt += coords[1] + " " + coords[0] + ",";
        }
        newWkt = newWkt.substring(0, newWkt.length() - 1) + "))";
        return newWkt;
    }

    public static String getFormatDate() {
        //SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        return df.format(new Date());
    }


    public static Map<String, String> province2pinyin = new HashMap<String, String>() {
        {
            put("安徽省", "anhui");
            put("北京市", "beijing");
            put("重庆市", "chongqing");
            put("福建省", "fujian");
            put("甘肃省", "gansu");
            put("广东省", "guangdong");
            put("广西壮族自治区", "guangxi");
            put("贵州省", "guizhou");
            put("海南省", "hainan");
            put("河北省", "hebei");
            put("黑龙江省", "heilongjiang");
            put("河南省", "henan");
            put("湖北省", "hubei");
            put("湖南省", "hunan");
            put("江苏省", "jiangsu");
            put("江西省", "jiangxi");
            put("吉林省", "jilin");
            put("辽宁省", "liaoning");
            put("内蒙古自治区", "neimenggu");
            put("宁夏回族自治区", "ningxia");
            put("山东省", "shandong");
            put("上海市", "shanghai");
            put("山西省", "shanxi");
            put("陕西省", "shanxi2");
            put("四川省", "sichuan");
            put("天津市", "tianjin");
            put("新疆维吾尔自治区", "xinjiang");
            put("西藏自治区", "xizang");
            put("云南省", "yunnan");
            put("浙江省", "zhejiang");
            put("青海省", "qinghai");
            put("新疆生产建设兵团", "xjbingtuan");
        }
    };
    public static String getSpecialTableName(String province, String city, String area, String type, boolean isNewTable) {
        String tableName = "";
        if ("PGA".equals(type)) {
            tableName = "qh_probability_earthquake_danger";
        } else if ("POINT".equals(type)) {
            tableName = "qh_risk_level_map_point";
        }
        //System.out.println(province +  city +  area);

        if (isNewTable) {
            if (province != null && province2pinyin.containsKey(province)) {
                tableName = tableName + "_" + province2pinyin.get(province);
            }
        }
        return tableName;
    }

    //zyt--获取省级表名
    public static String getSpecialTableNameProvince(String province, String city, String area, String type, boolean isNewTable) {
        String tableName = "";
        if ("PGA".equals(type)) {
            tableName = "qh_probability_earthquake_danger_province";
        } else if ("POINT".equals(type)) {
            tableName = "qh_risk_level_map_point_province";
        } else if ("SCR".equals(type)) {
            tableName = "qh_site_class_result";
        }
        //System.out.println(province +  city +  area);

        if (isNewTable) {
            if (province != null && province2pinyin.containsKey(province)) {
                tableName = tableName + "_" + province2pinyin.get(province);
            }
        }
        return tableName;
    }

    //zyt校验空间分辨率是否为6秒--判断最小距离是否小于200米
    /**
     * 地球半径,单位 km
     */
    private static final double EARTH_RADIUS = 6378.137;

    /**
     * 根据经纬度，计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lng1 = Math.toRadians(longitude1);
        double lng2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lng1 - lng2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘地球半径, 返回单位: 千米
        s =  s * EARTH_RADIUS;
        return s;
    }

    //判断6秒距离200
    public static boolean isLessSixSecondDistance(List<Double> allLonList,List<Double> allLatList) {
        /*for(int i=0;i<allLonList.size();i++){
            double lng1 = allLonList.get(i);
            double lat1 = allLatList.get(i);
            for(int j=i+1;j<allLonList.size();j++){
                double lng2 = allLonList.get(j);
                double lat2 = allLatList.get(j);
                double distance = getDistance(lng1,lat1,lng2,lat2);
                if(distance<0.2){//200米
                    return true;
                }
            }
        }

        return false;*/

        for(int i=0;i<allLonList.size();i++){
            if(i>100){//只判断100个点
                break;
            }
            double lng1 = allLonList.get(i);
            double lat1 = allLatList.get(i);
            boolean bool = false;
            double minDistance = -1;//最小距离
            for(int j=0;j<allLonList.size();j++){
                if(j==i){
                    continue;
                }
                double lng2 = allLonList.get(j);
                double lat2 = allLatList.get(j);
                double distance = getDistance(lng1,lat1,lng2,lat2);
                if(minDistance==-1 || distance<minDistance){
                    minDistance = distance;
                }
                if(distance<0.25){//250米
                    bool = true;
                    break;
                }
            }
            if(bool==false){
                System.out.println("第"+i+"条数据判断6秒距离不在250米内："+minDistance+"km--minDistance");
                System.out.println("第"+i+"条数据经纬度："+lng1+","+lat1);
                return false;
            }
        }

        return true;
    }

    /*//校验点空间位置是否不重叠
    public static boolean isPointNotOverlap(List<Double> allLonList,List<Double> allLatList) {
        boolean bool = true;
        int count = 0;
        for(int i=0;i<allLonList.size();i++){
            double lng1 = allLonList.get(i);
            double lat1 = allLatList.get(i);
            for(int j=0;j<allLonList.size();j++){
                if(j==i){
                    continue;
                }
                double lng2 = allLonList.get(j);
                double lat2 = allLatList.get(j);
                if(lng1==lng2 && lat1==lat2){
                    System.out.println("第"+i+"条数据和第"+j+"条数据空间位置重叠，经纬度："+lng1+","+lat1);
                    bool = false;
                    //return false;
                    count++;
                }
            }
        }
        System.out.println("共"+count+"条数据空间位置重叠。");

        return bool;
    }*/

    //校验点空间位置是否不重叠
    public static boolean isPointNotOverlap(List<String> allWktStrList) {
        boolean bool = true;
        int count = 0;
        for(int i=0;i<allWktStrList.size();i++){
            String wkt1 = allWktStrList.get(i);
            for(int j=i+1;j<allWktStrList.size();j++){
                String wkt2 = allWktStrList.get(j);
                if(wkt1==wkt2){
                    System.out.println("第"+i+"条数据和第"+j+"条数据空间位置重叠，经纬度："+wkt1);
                    bool = false;
                    //return false;
                    count++;
                }
            }
        }
        System.out.println("共"+count+"条数据空间位置重叠。");

        return bool;
    }

    private static boolean geometryIsEqualsCoordinate(String wkt, String lon, String lat) {
        //POINT (119.302 35.23300000088943)
        String wktPart = "";
        if (wkt.toLowerCase().indexOf("multipoint") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 2, wkt.lastIndexOf(")") - 1);
        } else if (wkt.toLowerCase().indexOf("point") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 1, wkt.lastIndexOf(")"));
        }

        int det = 1 + 6;
        String[] array = wktPart.split(" ");
        String longitude = array[0], latitude = array[1];
        String newWktLongitudeStr = keepDecimalDigits(longitude, det), newWktLatitudeStr = keepDecimalDigits(latitude, det);
        String newLongitudeStr = keepDecimalDigits(lon, det), newLatitudeStr = keepDecimalDigits(lat, det);

        double newWktLongitude = Double.parseDouble(newWktLongitudeStr), newWktLatitude = Double.parseDouble(newWktLatitudeStr);
        double newLongitude = Double.parseDouble(newLongitudeStr), newLatitude = Double.parseDouble(newLatitudeStr);

        if (newWktLongitude == newLongitude && newWktLatitude == newLatitude) return true;
        return false;
    }

    private static String keepDecimalDigits(String floatStr, int det) {
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        int temp=det+3;
        String tempfloatPart=floatStr.substring(index + 1, (len > (index + temp)) ? (index + temp) : len);
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);
        if(tempfloatPart.length()>floatPart.length()&&tempfloatPart.startsWith(floatPart)&&floatPart.endsWith("9")){
            int findex=0;
            String sindex="";
            for(int i=floatPart.length()-1;i>0;i--){
                String subStr = floatPart.substring(i, i+1);
                if(subStr.equals("9")){
                    continue;
                }
                findex=i;
                sindex=Integer.toString(Integer.parseInt(subStr)+1);
                break;
            }
            floatPart= floatPart.substring(0, findex)+ sindex;
        }
        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;
        return newFloatStr;
    }

    //1.校验GeometryIsNotEqualsCoordinate
    public String checkGeometryIsNotEqualsCoordinate(List<List<Object>> list){
        for (int i = 0; i < list.size(); i++) {
            List<Object> attributes = list.get(i);
            //校验GeometryIsNotEqualsCoordinate
            String pointWkt = attributes.get(0).toString();
            String A = attributes.get(1).toString();
            String B = attributes.get(2).toString();
            if (!geometryIsEqualsCoordinate(pointWkt, A, B)) return "GeometryIsNotEqualsCoordinate";
        }

        return "校验成功";
    }

    //2.校验是否有乱码
    public int checkIsHaveMsssyCode(List<List<Object>> list){
        int msssyIndex = -1;
        for (int i = 0; i < list.size(); i++) {
            List<Object> attributes = list.get(i);
            //校验是否有乱码
            for (int j = 0; j < attributes.size(); j++) {
                String value = attributes.get(j).toString();
                for (int k = 0; k < value.length() / 2; k++) {
                    char c = value.charAt(k);
                    // 当从Unicode编码向某个字符集转换时，如果在该字符集中没有对应的编码，则得到0x3f（即问号字符?）
                    //从其他字符集向Unicode编码转换时，如果这个二进制数在该字符集中没有标识任何的字符，则得到的结果是0xfffd
                    if ((int) c == 0xfffd) {
                        // 存在乱码
                        msssyIndex = i;
                        break;
                    }
                }
                if(msssyIndex!=-1){
                    break;
                }
            }
            if(msssyIndex!=-1){
                break;
            }
        }

        return msssyIndex;
    }

    //3.校验字段空值
    public String checkFieldNullValue(List<List<Object>> list){
        for (int i = 0; i < list.size(); i++) {
            List<Object> attributes = list.get(i);
            //校验是否有乱码
            for (int j = 0; j < attributes.size(); j++) {
                String value = attributes.get(j).toString();
                //校验字段空值
                if (value == null || "".equals(value.trim())) return "fieldNullValue";
            }
        }

        return "校验成功";
    }

    //4.校验空间分辨率不是6秒
    public String checkLessSixSecond(List<List<Object>> list){
        Map<Double, List<Double>> lon2latitudes = new HashMap<>();
        Map<Double, List<Double>> lat2longitudes = new HashMap<>();
        double lon = 0, lat = 0;
        for (int i = 0; i < list.size(); i++) {
            List<Object> attributes = list.get(i);
            String A = attributes.get(1).toString();
            String B = attributes.get(2).toString();
            //校验空间分辨率不是6秒
            lon = Double.parseDouble(A);
            lat = Double.parseDouble(B);
            if (lon2latitudes.containsKey(lon)) {
                lon2latitudes.get(lon).add(lat);
            } else {
                List<Double> latitudes = new ArrayList<>();
                latitudes.add(lat);
                lon2latitudes.put(lon, latitudes);
            }
            if (lat2longitudes.containsKey(lat)) {
                lat2longitudes.get(lat).add(lon);
            } else {
                List<Double> longitudes = new ArrayList<>();
                longitudes.add(lon);
                lat2longitudes.put(lat, longitudes);
            }
        }
        //校验空间分辨率不是6秒
        if (!(isLessSixSecond(lon2latitudes) || isLessSixSecond(lat2longitudes))){
            return "SpatialResolutionError";
        }

        return "校验成功";
    }

    private static boolean isLessSixSecond(Map<Double, List<Double>> map) {
        double thresh = 6.5;
        for(Map.Entry<Double, List<Double>> entity : map.entrySet()) {
            List<Double> entityValues = entity.getValue();
            Collections.sort(entityValues);
            for (int i = 0; i < entityValues.size() - 1; i++) {
                double value1 = entityValues.get(i), value2 = entityValues.get(i + 1);
                double det = Math.abs(value1 - value2);
                if (det >= 1) return false;
                det *= 60;
                if (det >= 1) return false;
                det *= 60;
                if (det < thresh) return true;
            }
        }
        return false;
    }

    //读取shp文件并校验--type上传类型（行政区划_）
    public static List<Object> readSHPFileCheck(String path, String codeType,String type, String boundariesCoordinate) {
        List<Object> result = new ArrayList<Object>();
        String prjPath = path.substring(0, path.length() - 4) + ".prj";
        String strWKTMercator = readPRJ(prjPath);
        if (strWKTMercator != "") ProjectTransUtil.setStrWKTMercator(strWKTMercator);
        String lonLatStr = "", wkt = "";
        SimpleFeatureCollection colls1 = readShp(path, codeType);
        SimpleFeatureIterator iters = colls1.features();
        String resMsg = "校验成功";
        int count = 0;
        //校验空间分辨率不是6秒
        double lon = 0, lat = 0;
        /*Map<Double, List<Double>> lon2latitudes = new HashMap<>();
        Map<Double, List<Double>> lat2longitudes = new HashMap<>();*/
        /*List<String> allWktStrList = new ArrayList<String>();//全部空间信息字符串列表*/
        List<Double> allLonList = new ArrayList<Double>();
        List<Double> allLatList = new ArrayList<Double>();
        SimpleFeature sf = null;
        //校验是否为罗马数字
        String roman = "Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ", arab = "1 2 3 4", level = "";//修改等级值范围为1-4
        String SCR_arab = "1 2 3 4 9 10";//场地类型
        //校验矢量面是否在省市县所在区域内
        List<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon>> multiPolygonList = new ArrayList<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon>>();
        List<Geometry> multiPolygonGeometryList = new ArrayList<Geometry>();
        //Geometry boundariesGeometry = null;//行政区域
        /*//只有矢量面判断是否在行政区划范围内
        if("RLMPolygon_".equals(type)){
            boundariesGeometry = getPolygonGeometryList(boundariesCoordinate);//行政区域
        }*/
        //boundariesGeometry = getPolygonGeometryList(boundariesCoordinate);//行政区域
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries = getDistrictBoundaryByString(boundariesCoordinate);
        //zyt-test
        boolean tempBool = true;//判断是否需要转换经纬度值
        while (iters.hasNext()) {
            if(count%100000==0){
                System.out.println(count);
            }
            sf = iters.next();
            List<Object> attributes = sf.getAttributes();
            //0.判断字段数量是否符合要求
            int size = attributes.size();
            if("PED_".equals(type)){
                if(size<11){
                    resMsg = "fieldNumError";
                    break;
                }
            }else if("RLM_".equals(type)){
                if(size<4){
                    resMsg = "fieldNumError";
                    break;
                }
            }else if("RLMPolygon_".equals(type)){
                if(size<2){
                    resMsg = "fieldNumError";
                    break;
                }
            }else if("SCR_".equals(type)){
                if(size<2){
                    resMsg = "fieldNumError";
                    break;
                }
            }
            if(tempBool){
                wkt = attributes.get(0).toString();
                if (wkt.indexOf("MULTIPOINT") != -1) {
                    lonLatStr = reverseWktMultiPoint(ProjectTransUtil.wkt2lonLat(wkt));
                } else if (wkt.indexOf("POINT") != -1) {
                    lonLatStr = reverseWktPoint(ProjectTransUtil.wkt2lonLat(wkt));
                } else if (wkt.indexOf("MULTIPOLYGON") != -1) {
                    lonLatStr = reverseWktMultiPolygon(ProjectTransUtil.wkt2lonLat(wkt));
                } else if (wkt.indexOf("POLYGON") != -1) {
                    lonLatStr = reverseWktPolygon(ProjectTransUtil.wkt2lonLat(wkt));
                }
                attributes.set(0, lonLatStr);
                //判断是否经纬度值是否相等
                if(wkt.equals(lonLatStr)){
                    tempBool = false;//判断是否需要转换经纬度值
                }
            }
            //校验矢量面是否在省市县所在区域内
            if("RLMPolygon_".equals(type)){
                //根据属性获取矢量面列表
                List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> polygonList = getPolygonList(attributes);
                //校验数据是否在省市县所在区域边界内
                /*if(!newCheckPointIsInDistrict(boundaries, polygonList)){
                    resMsg = "PointIsNotInDistrict";
                    break;
                }*/

                //添加到面经纬度列表用于校验面是否相交
                multiPolygonList.add(polygonList);
                //test
                Geometry polygon = getPolygonGeometryList(attributes.get(0).toString());
                multiPolygonGeometryList.add(polygon);
            }
            if("PED_".equals(type) || "RLM_".equals(type)){
                //1.校验GeometryIsNotEqualsCoordinate
                String pointWkt = attributes.get(0).toString();
                String A = attributes.get(1).toString();
                String B = attributes.get(2).toString();
                /*if (!geometryIsEqualsCoordinate(pointWkt, A, B)) {
                    resMsg = "GeometryIsNotEqualsCoordinate";
                    break;
                }*/
                //新校验经纬度方法
                if (!newGeometryIsEqualsCoordinate(pointWkt, A, B)) {
                    resMsg = "GeometryIsNotEqualsCoordinate";
                    break;
                }

                //可注释判断以下判断点是否在行政区划内代码
                /*//判断点是否在行政区划内
                if(!newCheckPointIsInDistrictBoundary(boundaries,A,B)){
                    resMsg = "PointIsNotInDistrict";
                    break;
                }*/
                /*if(count<10){//仅判断10个点
                    //判断点是否在行政区划内
                    if(!newCheckPointIsInDistrictBoundary(boundaries,A,B)){
                        resMsg = "PointIsNotInDistrict";
                        break;
                    }
                }*/
            }
            //2.校验是否有乱码
            int msssyIndex = -1;
            //校验是否有乱码
            for (int j = 0; j < attributes.size(); j++) {
                if(attributes.get(j)==null){
                    continue;
                }
                String value = attributes.get(j).toString();
                for (int k = 0; k < value.length() / 2; k++) {
                    char c = value.charAt(k);
                    // 当从Unicode编码向某个字符集转换时，如果在该字符集中没有对应的编码，则得到0x3f（即问号字符?）
                    //从其他字符集向Unicode编码转换时，如果这个二进制数在该字符集中没有标识任何的字符，则得到的结果是0xfffd
                    if ((int) c == 0xfffd) {
                        // 存在乱码
                        msssyIndex = count;
                        break;
                    }
                }
                if(msssyIndex!=-1){
                    resMsg = "messyCode#"+msssyIndex;
                    break;
                }
            }
            if(msssyIndex!=-1){
                break;
            }
            //3.校验字段空值
            for (int j = 0; j < attributes.size(); j++) {
                if(attributes.get(j)==null){
                    resMsg = "fieldNullValue";
                    break;
                }
                String value = attributes.get(j).toString();
                //校验字段空值
                if (value == null || "".equals(value.trim())){
                    resMsg = "fieldNullValue";
                    break;
                }
            }
            if(!resMsg.equals("校验成功")){
                break;
            }
            //上传类型（行政区划_）
            if (("PED_".equals(type) || "RLM_".equals(type))) {
                /*//4.校验空间分辨率不是6秒
                lon = Double.parseDouble(A);
                lat = Double.parseDouble(B);
                if (lon2latitudes.containsKey(lon)) {
                    lon2latitudes.get(lon).add(lat);
                } else {
                    List<Double> latitudes = new ArrayList<>();
                    latitudes.add(lat);
                    lon2latitudes.put(lon, latitudes);
                }
                if (lat2longitudes.containsKey(lat)) {
                    lat2longitudes.get(lat).add(lon);
                } else {
                    List<Double> longitudes = new ArrayList<>();
                    longitudes.add(lon);
                    lat2longitudes.put(lat, longitudes);
                }*/
                //4.校验空间分辨率不是6秒
                String A = attributes.get(1).toString();
                String B = attributes.get(2).toString();
                lon = Double.parseDouble(A);
                lat = Double.parseDouble(B);
                allLonList.add(lon);
                allLatList.add(lat);
                //校验是否空间位置重叠
                /*allWktStrList.add(attributes.get(0).toString());*/
            }
            //4.校验是否为罗马数字
            if ("RLM_".equals(type)) {
                level = attributes.get(3).toString();
                if (arab.indexOf(level) == -1){
                    resMsg = "levelError";
                    System.out.println("levelError:"+level);
                    break;
                }
            } else if ("RLMPolygon_".equals(type)) {
                level = attributes.get(1).toString();
                if (arab.indexOf(level) == -1){
                    resMsg = "levelError";
                    System.out.println("levelError:"+level);
                    break;
                }
            } else if ("SCR_".equals(type)) {
                level = attributes.get(1).toString();
                if (SCR_arab.indexOf(level) == -1 || level=="0"){
                    resMsg = "levelError";
                    System.out.println("levelError:"+level);
                    break;
                }
            }

            count++;
        }
        iters.close();
        System.out.println(count);
        //上传类型（行政区划_）
        if (("PED_".equals(type) || "RLM_".equals(type)) && resMsg.equals("校验成功")) {
            /*//校验空间分辨率不是6秒
            if (!(isLessSixSecond(lon2latitudes) || isLessSixSecond(lat2longitudes))){
                resMsg = "SpatialResolutionError";
            }*/
            //校验空间分辨率不是6秒
            if (!(isLessSixSecondDistance(allLonList,allLatList))){
                resMsg = "SpatialResolutionError";
            }
            /*//校验点空间位置是否不重叠
            if(!isPointNotOverlap(allWktStrList)){
                resMsg = "PointOverlapError";
            }*/
        }
        //校验矢量面是否在存在两两相交（或自相交）
        if("RLMPolygon_".equals(type) && resMsg.equals("校验成功")){
            //校验矢量面是否在存在自相交
            String resultStr = checkIsPolygonsIntersect(multiPolygonList);
            if(resultStr!="校验成功"){
                resMsg = resultStr;
            }
            if(resMsg.equals("校验成功")){
                //校验矢量面是否在存在两两相交
                resultStr = checkIsPolygonGeometrysIntersect(multiPolygonGeometryList);
                if(resultStr!="校验成功"){
                    resMsg = resultStr;
                }
            }
        }
        //返回结果
        result.add(codeType);//编码类型（0：UTF-8，1：GBK）
        result.add(count);//数据长度
        result.add(resMsg);//校验结果
        //校验是否有乱码
        if(resMsg.indexOf("messyCode")!=-1 && !codeType.equals("GBK")){
            result = VectorDataUtil.readSHPFileCheck(path, "GBK",type, boundariesCoordinate);
        }

        return result;
    }

    /*zyt--新校验GeometryIsNotEqualsCoordinate*/
    public static boolean newGeometryIsEqualsCoordinate(String wkt, String lon, String lat) {
        String wktPart = "";
        if (wkt.toLowerCase().indexOf("multipoint") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 2, wkt.lastIndexOf(")") - 1);
        } else if (wkt.toLowerCase().indexOf("point") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 1, wkt.lastIndexOf(")"));
        }

        int det = 1 + 8;//保留8位小数判断
        String[] array = wktPart.split(" ");
        String longitude = array[0], latitude = array[1];
        String newWktLongitudeStr = newKeepDecimalDigits(longitude, det), newWktLatitudeStr = newKeepDecimalDigits(latitude, det);
        String newLongitudeStr = newKeepDecimalDigits(lon, det), newLatitudeStr = newKeepDecimalDigits(lat, det);

        double newWktLongitude = Double.parseDouble(newWktLongitudeStr), newWktLatitude = Double.parseDouble(newWktLatitudeStr);
        double newLongitude = Double.parseDouble(newLongitudeStr), newLatitude = Double.parseDouble(newLatitudeStr);

        //if (newWktLongitude == newLongitude && newWktLatitude == newLatitude) return true;
        //判断是否在10-6次方内
        double tempLon = Math.abs(newWktLongitude - newLongitude);
        double tempLat = Math.abs(newWktLatitude - newLatitude);
        if(tempLon<0.000001 && tempLat<0.000001){
            return true;
        }

        //判断保留8位（不四舍五入）属性字段经纬度与geometry是否一致
        if(getGeometryIsEqualsCoordinateBool(longitude, latitude, lon, lat, det)) return true;

        return false;
    }

    private static String newKeepDecimalDigits(String floatStr, int det) {
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        int temp=det+1;
        String tempfloatPart=floatStr.substring(index + 1, (len > (index + temp)) ? (index + temp) : len);
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);

        boolean bool = false;//判断是否四舍五入
        int findex=0;
        String sindex="";
        if(tempfloatPart.length()>floatPart.length()){
            if(tempfloatPart.startsWith(floatPart)&&(tempfloatPart.endsWith("9") || tempfloatPart.endsWith("8") || tempfloatPart.endsWith("7") || tempfloatPart.endsWith("6") || tempfloatPart.endsWith("5"))){
                for(int i=floatPart.length()-1;i>=0;i--){
                    String subStr = floatPart.substring(i, i+1);
                    if(subStr.equals("9")){
                        continue;
                    }
                    findex=i;
                    sindex=Integer.toString(Integer.parseInt(subStr)+1);
                    break;
                }
                floatPart= floatPart.substring(0, findex)+ sindex;
                bool = true;
            }
        }

        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;
        if(bool && sindex.equals("")){//floatPart都是9
            newFloatStr = Integer.toString(Integer.parseInt(floatStr.substring(0, index))+1);
        }

        return newFloatStr;
    }

    //保留8位（不四舍五入）
    private static String newKeepDecimalDigits2(String floatStr, int det) {
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);
        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;

        return newFloatStr;
    }

    //判断保留8位（不四舍五入）属性字段经纬度与geometry是否一致
    private static boolean getGeometryIsEqualsCoordinateBool(String longitude, String latitude, String lon, String lat, int det){
        boolean bool = false;
        String newWktLongitudeStr = newKeepDecimalDigits2(longitude, det), newWktLatitudeStr = newKeepDecimalDigits2(latitude, det);
        String newLongitudeStr = newKeepDecimalDigits2(lon, det), newLatitudeStr = newKeepDecimalDigits2(lat, det);

        double newWktLongitude = Double.parseDouble(newWktLongitudeStr), newWktLatitude = Double.parseDouble(newWktLatitudeStr);
        double newLongitude = Double.parseDouble(newLongitudeStr), newLatitude = Double.parseDouble(newLatitudeStr);

        /*if (newWktLongitude == newLongitude && newWktLatitude == newLatitude){
            bool= true;
        }*/
        //判断是否在10-6次方内
        double tempLon = Math.abs(newWktLongitude - newLongitude);
        double tempLat = Math.abs(newWktLatitude - newLatitude);
        if(tempLon<0.000001 && tempLat<0.000001){
            bool= true;
        }

        return bool;
    }

    //截取8位小数（不四舍五入）
    public static String getNewDecimalDigits(String floatStr) {
        int det = 1 + 8;
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);
        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;

        return newFloatStr;
    }

    //根据属性获取boundary.Point数组列表
    public static List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> getPolygonList(List<Object> attributes) {
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> pointArray0 = null;//面点数组
        List<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point>> noPointList = null;//镂空的面点数组列表
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> pointArray = null;
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = null;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> polygonList = new ArrayList<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon>();
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon polygon = null;

        String coordinates = attributes.get(0).toString();
        try{
            if (coordinates.indexOf("MULTIPOLYGON") != -1) {
                coordinates = coordinates.substring(coordinates.indexOf("(((") + 3, coordinates.lastIndexOf(")))"));
                if (coordinates.indexOf(")), ((") != -1) {//多个面
                    coordinates = coordinates.replace(")), ((", "|");
                    coordinates = coordinates.replace("), (", "#");
                    String[] geometries = StringUtils.split(coordinates, "|");
                    for (int j = 0; j < geometries.length; j++) {
                        String geometry = geometries[j];
                        //获取面
                        polygon = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon(geometry);
                        polygonList.add(polygon);
                    }

                }else if (coordinates.indexOf("), (") != -1) {//单个面（包括镂空的面）
                    coordinates = coordinates.replace("), (", "#");
                    //获取面
                    polygon = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon(coordinates);
                    polygonList.add(polygon);

                }else{//单个面
                    //获取面
                    polygon = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon(coordinates);
                    polygonList.add(polygon);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            //System.out.println("矢量面："+attributes.get(0).toString());
        }

        return polygonList;
    }

    //根据属性获取矢量面Geometry
    public static Geometry getPolygonGeometryList(String coordinates) {
        Geometry geometry = null;
        try{
            geometry = reader.read(coordinates);
        }catch (Exception e){
            e.printStackTrace();
        }

        return geometry;
    }

    //private static double GLOBAL_THRESH = 1E-8;
    private static double GLOBAL_THRESH = 1E-6;
    //校验矢量面数据是否在省市县所在区域边界内
    public static boolean newCheckPointIsInDistrict(List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries, List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> polygonList) {
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = null;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> pointArray = null;
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] boundary = null;
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon polygon = null;

        if(boundaries!=null && boundaries.size()>0 && polygonList!=null && polygonList.size()>0){
            for(int i=0;i<polygonList.size();i++){
                boolean bool = false;
                polygon = polygonList.get(i);
                pointArray = polygon.points;
                if(pointArray!=null && pointArray.size()>0){
                    for(int j=0;j<pointArray.size();j++){
                        point = pointArray.get(j);
                        bool = false;
                        double minDis = Double.MAX_VALUE;
                        for (int k = 0; k < boundaries.size(); k++) {
                            boundary = boundaries.get(k);
                            if (AreaBoundaryUtil.isPointInPolygon(point, boundary)){
                                bool = true;
                                break;
                            } else {//判断容差距离
                                //double minDis = Double.MAX_VALUE;
                                for (int n = 0; n < boundary.length - 1; n++) {
                                    com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p1 = boundary[n], p2 = boundary[n + 1];
                                    double d = AreaBoundaryUtil.pointToLine(p1.x, p1.y, p2.x, p2.y, point.x, point.y);
                                    if (minDis > d) minDis = d;
                                }
                                if (minDis < GLOBAL_THRESH) {
                                    bool = true;
                                    break;
                                }
                            }
                        }
                        if (bool == false){
                            String temp = "矢量面上的点："+point;
                            /*temp += "存在于面：MULTIPOLYGON (((";
                            for (int n = 0; n < pointArray.size(); n++) {
                                temp += pointArray.get(n).x+" "+pointArray.get(n).y+", ";
                            }
                            temp+=")))";*/
                            temp+="--------不在行政区划范围内----minDis:"+minDis;
                            System.out.println(temp);
                            return false;
                        }
                    }
                }
            }
        }else{
            System.out.println("无行政区划范围----");
            return false;
        }

        return true;
    }

    //校验矢量面是否在存在两两重叠或相交（或单要素自相交）
    public static String checkIsPolygonGeometrysIntersect(List<Geometry> multiPolygonGeometryList) {
        String resultStr = "校验成功";
        Geometry geometry1 = null;
        Geometry geometry2 = null;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> polygonList = null;
        if(multiPolygonGeometryList!=null && multiPolygonGeometryList.size()>0) {
            for (int i = 0; i < multiPolygonGeometryList.size(); i++) {
                geometry1 = multiPolygonGeometryList.get(i);
                //Geometry geometry1IntersectGeometry1 = geometry1.intersection(geometry1);
                //判断是否存在两两重叠或相交
                for(int j=i+1;j<multiPolygonGeometryList.size();j++){
                    geometry2 = multiPolygonGeometryList.get(j);
                    //自相交
                    //Geometry geometry2IntersectGeometry2 = geometry2.intersection(geometry2);
                    //Geometry geometry1IntersectGeometry2 = geometry1IntersectGeometry1.intersection(geometry2IntersectGeometry2);
                    //double area = geometry1IntersectGeometry2.getArea();
                    //两两相交
                    Geometry geometry1IntersectGeometry2 = geometry1.intersection(geometry2);
                    double area = geometry1IntersectGeometry2.getArea();
                    if(area >= GLOBAL_THRESH){
                        resultStr = "isPolygonsIntersect";
                        String temp = "存在两两重叠或相交";
                        //temp += "，面："+geometry1.toString();
                        //temp += "相交于面："+geometry2.toString();
                        temp += "，相交面积："+area;
                        System.out.println(temp);
                        break;
                    }
                }
                if(resultStr!="校验成功"){
                    break;
                }
            }
        }

        return resultStr;
    }

    //校验矢量面是否在存在单要素自相交
    public static String checkIsPolygonsIntersect(List<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon>> multiPolygonList) {
        String resultStr = "校验成功";
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon polygon = null;
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon polygon1 = null;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> polygonList = null;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon> allPolygonList = null;//全部面列表
        if(multiPolygonList!=null && multiPolygonList.size()>0) {
            allPolygonList = new ArrayList<com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon>();
            for (int n = 0; n < multiPolygonList.size(); n++) {
                polygonList = multiPolygonList.get(n);
                for (int i = 0; i < polygonList.size(); i++) {
                    allPolygonList.add(polygonList.get(i));
                }
            }
        }
        if(allPolygonList!=null && allPolygonList.size()>0) {
            for (int i = 0; i < allPolygonList.size(); i++) {
                polygon = allPolygonList.get(i);
                //判断矢量面是否存在自相交
                if(checkIsPolygonSelfIntersect(polygon)){
                    resultStr = "isPolygonSelfIntersect";
                    String temp = "面自相交";
                    /*temp += "：POLYGON((";
                    for (int n = 0; n < polygon.points.size(); n++) {
                        temp += polygon.points.get(n).x+" "+polygon.points.get(n).y+", ";
                    }
                    temp+="))";*/
                    System.out.println(temp);
                    break;
                }
                /*if(i<(polygonList.size()-1)){
                    for(int j=i+1;j<polygonList.size();j++){
                        polygon1 = polygonList.get(j);
                        //判断两多边形面是否重叠或相交
                        if(isPolygonsOverlapContains(polygon,polygon1)){
                            resultStr = "isPolygonsIntersect";
                            break;
                        }
                    }
                    if(resultStr!="校验成功"){
                        break;
                    }
                }*/
            }
        }

        return resultStr;
    }

    //判断矢量面是否存在自相交
    private static boolean checkIsPolygonSelfIntersect(com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon polygon){
        boolean bool = false;//不存在自相交
        int flag = 0;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> points = polygon.points;
        for(int i = 0;i < (points.size()-1);i++){ //循环开始元素
            for(int j = i + 1;j < points.size();j++){ //循环后续所有元素
                //如果相等，则重复
                if(points.get(i).x == points.get(j).x && points.get(i).y == points.get(j).y){
                    flag++; //设置标志变量为重复
                }
            }
        }
        if(flag>1){//除首尾点外存在重复的点
            bool = true;//存在自相交
        }

        return bool;
    }

    //根据点获取矢量面（单面）
    public static Geometry getPolygonByPointList(List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> points){
        Geometry geometry = null;
        String coordinates = "";
        try{
            com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = null;
            if(points!=null && points.size()>0){
                for(int i=0;i<points.size();i++){
                    point = points.get(i);
                    coordinates += point.x + " " +point.y + ", ";
                }
                coordinates = coordinates.substring(0, coordinates.length() - 2);
            }
            coordinates = "POLYGON (("+coordinates+"))";
            geometry = reader.read(coordinates);
        }catch (Exception e){
            e.printStackTrace();
            //System.out.println("面："+coordinates);
        }

        return geometry;
    }

    //判断面是否相交，判断矢量面polygon与矢量面boundariesGeometry内（镂空noGeometryList）相交面积
    public static boolean newCheckPolygonIsInPolygonIntersect(Geometry polygon,Geometry boundariesGeometry,List<Geometry> noGeometryList) {
        boolean bool = false;//不相交
        try{
            Geometry polygonIntersectGeometry = polygon.intersection(boundariesGeometry);
            double area = polygonIntersectGeometry.getArea();
            if(area >= GLOBAL_THRESH){
                if(noGeometryList!=null && noGeometryList.size()>0) {
                    double areaTemp = 0;
                    for (int j = 0; j < noGeometryList.size(); j++) {
                        Geometry geometry = noGeometryList.get(j);
                        polygonIntersectGeometry = polygon.intersection(geometry);
                        areaTemp += polygonIntersectGeometry.getArea();
                    }
                    area = area - areaTemp;
                    if(area >= GLOBAL_THRESH){
                        bool = true;//相交
                    }
                }else{
                    bool = true;//相交
                }
                if(bool){
                    String temp = "矢量面相交面积："+area;
                    //temp += "__面："+polygon.toString();
                    //System.out.println(temp);
                    //temp = "与矢量面相交："+boundariesGeometry.toString()+"--------矢量面相交----";
                    System.out.println(temp);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return bool;
    }

    //判断面是否相交，判断矢量面polygon的每个点是否在矢量面boundariesGeometry内（镂空noGeometryList）
    public static boolean newCheckPolygonIsInPolygon(Geometry polygon,Geometry boundariesGeometry,List<Geometry> noGeometryList) {
        boolean bool = false;
        try{
            Coordinate[] boundaries = boundariesGeometry.getCoordinates();
            Coordinate[] points = polygon.getCoordinates();
            List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaryList = null;
            if(points!=null && points.length>0){
                for(int i=0;i<points.length;i++){
                    bool = false;
                    Coordinate coord = points[i];
                    Geometry point = geometryFactory.createPoint(coord);
                    if(point.within(boundariesGeometry)){//判断点是否在矢量面内（不包含边界）
                        bool = true;
                    }
                    if(bool){//点在矢量面boundariesGeometry内
                        if(noGeometryList!=null && noGeometryList.size()>0){
                            boolean boolTemp = false;
                            for(int j=0;j<noGeometryList.size();j++){
                                Geometry geometry = noGeometryList.get(j);
                                /*if(point.within(geometry)){//判断点是否在镂空面内（包含边界）
                                    boolTemp = true;
                                    break;
                                }*/
                                //判断点是否在镂空面内（包含边界）
                                com.css.fxfzdzzh.modules.spatialData.repository.entity.Point pointTemp = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point(point.getCoordinate().x, point.getCoordinate().y);
                                //获取POLYGON面所在区域边界列表
                                boundaryList = getPolygonPointsListByString(geometry.toString());
                                if(boundaryList!=null && boundaryList.size()==1){
                                    //校验点数据是否在面所在区域边界内
                                    if(newCheckPointIsInPolygonBoundary(pointTemp, boundaryList.get(0))){
                                        boolTemp = true;
                                        break;
                                    }
                                }
                            }
                            if(boolTemp){//点在镂空面内（包含边界）
                                bool = false;//不相交
                            }else{
                                String temp = "矢量面上的点："+point;
                                //temp += "存在于面："+polygon.toString();
                                //System.out.println(temp);
                                //temp = "与矢量面相交："+boundariesGeometry.toString();
                                temp += "--------矢量面相交----";
                                System.out.println(temp);
                                break;
                            }
                        }else{
                            String temp = "矢量面上的点："+point;
                            //temp += "存在于面："+polygon.toString();
                            //System.out.println(temp);
                            //temp = "与矢量面相交："+boundariesGeometry.toString();
                            temp += "--------矢量面相交----";
                            System.out.println(temp);
                            break;
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return bool;
    }

    //判断两多边形面是否重叠或相交
    public static boolean isPolygonsOverlapContains(com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon plyA, com.css.fxfzdzzh.modules.spatialData.repository.entity.Polygon plyB) {
        boolean bool = false;
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> pointsA = plyA.points;//面
        List<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point>> noPointsListA = plyA.noPointsList;//镂空面数组
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> pointsB = plyB.points;//面
        List<List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point>> noPointsListB = plyB.noPointsList;//镂空面数组

        //根据点获取矢量面（单面）
        Geometry geometryA = getPolygonByPointList(pointsA);
        List<Geometry> noGeometryListA = null;
        if(noPointsListA!=null && noPointsListA.size()>0){
            noGeometryListA = new ArrayList<Geometry>();
            for(int i=0;i<noPointsListA.size();i++){
                noGeometryListA.add(getPolygonByPointList(noPointsListA.get(i)));
            }
        }
        Geometry geometryB = getPolygonByPointList(pointsB);
        List<Geometry> noGeometryListB = null;
        if(noPointsListB!=null && noPointsListB.size()>0){
            noGeometryListB = new ArrayList<Geometry>();
            for(int i=0;i<noPointsListB.size();i++){
                noGeometryListB.add(getPolygonByPointList(noPointsListB.get(i)));
            }
        }

        //面是否相交，即判断两多边形是否存在点与区域的包含关系(A的点在B的区域内或B的点在A的区域内)
        boolean a = newCheckPolygonIsInPolygon(geometryA,geometryB,noGeometryListB);//矢量面A是否在矢量面B内
        boolean b = newCheckPolygonIsInPolygon(geometryB,geometryA,noGeometryListA);//矢量面B是否在矢量面A内
        if(a || b){//相交
            bool = true;
        }

        /*//判断面是否相交，判断矢量面polygon与矢量面boundariesGeometry内（镂空noGeometryList）相交面积
        boolean a = newCheckPolygonIsInPolygonIntersect(geometryA,geometryB,noGeometryListB);//矢量面A是否在矢量面B内
        boolean b = newCheckPolygonIsInPolygonIntersect(geometryB,geometryA,noGeometryListA);//矢量面B是否在矢量面A内
        if(a || b){//相交
            bool = true;
        }*/

        return bool;
    }

    /**
     * 检查多边形是否包含了某点（判断是否包含在多边形内部，在多边形的边线或顶点上返回false）
     */
    public static boolean containsPoint(com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point, com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] polygon) {
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p1=null,p2=null;
        int verticesCount = polygon.length;
        int nCross = 0;
        for (int i = 0; i < verticesCount; ++ i) {
            p1 = polygon[i];
            p2 = polygon[(i + 1) % verticesCount];

            // 求解 y=p.y 与 p1 p2 的交点
            if ( p1.y == p2.y ) {   // p1p2 与 y=p0.y平行
                continue;
            }
            if ( point.y < Math.min(p1.y, p2.y) ) { // 交点在p1p2延长线上
                continue;
            }
            if ( point.y >= Math.max(p1.y, p2.y) ) { // 交点在p1p2延长线上
                continue;
            }
            // 求交点的 X 坐标
            double x = (point.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
            if ( x > point.x ) { // 只统计单边交点
                nCross++;
            }
        }
        // 单边交点为偶数，点在多边形之外
        return (nCross%2==1);
    }

    //判断点是否在另一平面图中
    public static boolean isPointInPolygonNew(com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point, List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point> polygon) {

        //下述代码来源：http://paulbourke.net/geometry/insidepoly/，进行了部分修改
        //基本思想是利用射线法，计算射线与多边形各边的交点，如果是偶数，则点在多边形外，否则
        //在多边形内。还会考虑一些特殊情况，如点在多边形顶点上，点在多边形边上等特殊情况。

        int N = polygon.size();
        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上，也算做点在多边形内，直接返回true
        int intersectCount = 0; //cross points count of x
        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p1, p2; //neighbour bound vertices
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p = point; //测试点

        p1 = polygon.get(0); //left vertex
        for (int i = 1; i <= N; ++i) { //check all rays
            if (p.x == p1.x && p.y == p1.y) {
                return boundOrVertex; //p is an vertex
            }

            p2 = polygon.get(i % N); //right vertex
            if (p.y < Math.min(p1.y, p2.y) || p.y > Math.max(p1.y, p2.y)) { //ray is outside of our interests
                p1 = p2;
                continue; //next ray left point
            }

            if (p.y > Math.min(p1.y, p2.y) && p.y < Math.max(p1.y, p2.y)) { //ray is crossing over by the algorithm (common part of)
                if (p.x <= Math.max(p1.x, p2.x)) { //x is before of ray
                    if (p1.y == p2.y && p.x >= Math.min(p1.x, p2.x)) { //overlies on a horizontal ray
                        return boundOrVertex;
                    }

                    if (p1.x == p2.x) { //ray is vertical
                        if (p1.x == p.x) { //overlies on a vertical ray
                            return boundOrVertex;
                        } else { //before ray
                            ++intersectCount;
                        }
                    } else { //cross point on the left side
                        double xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x; //cross point of x
                        if (Math.abs(p.x - xinters) < precision) { //overlies on a ray
                            return boundOrVertex;
                        }

                        if (p.x < xinters) { //before ray
                            ++intersectCount;
                        }
                    }
                }
            } else { //special case when ray is crossing through the vertex
                if (p.y == p2.y && p.x <= p2.x) { //p crossing over p2
                    com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p3 = polygon.get((i + 1) % N); //next vertex
                    if (p.y >= Math.min(p1.y, p3.y) && p.y <= Math.max(p1.y, p3.y)) { //p.y lies between p1.y & p3.y
                        ++intersectCount;
                    } else {
                        intersectCount += 2;
                    }
                }
            }
            p1 = p2; //next ray left point
        }

        if (intersectCount % 2 == 0) { //偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }

    //校验点数据是否在省市县所在区域边界内
    public static boolean newCheckPointIsInDistrictBoundary(List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries, String lonStr, String latStr) {
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point(Double.parseDouble(lonStr), Double.parseDouble(latStr));
        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] boundary = null;
        boolean bool = false;
        if(boundaries!=null && boundaries.size()>0){
            for (int k = 0; k < boundaries.size(); k++) {
                boundary = boundaries.get(k);
                if (AreaBoundaryUtil.isPointInPolygon(point, boundary)){
                    bool = true;
                    break;
                } else {//判断容差距离
                    double minDis = Double.MAX_VALUE;
                    for (int n = 0; n < boundary.length - 1; n++) {
                        com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p1 = boundary[n], p2 = boundary[n + 1];
                        double d = AreaBoundaryUtil.pointToLine(p1.x, p1.y, p2.x, p2.y, point.x, point.y);
                        if (minDis > d) minDis = d;
                    }
                    if (minDis < GLOBAL_THRESH) {
                        bool = true;
                        break;
                    }
                }
            }
            if (bool == false){
                String temp = "点："+point+"--------不在行政区划范围内----";
                System.out.println(temp);
                return false;
            }
        }else{
            System.out.println("无行政区划范围----");
            return false;
        }

        return true;
    }

    //校验点数据是否在面所在区域边界内
    public static boolean newCheckPointIsInPolygonBoundary(com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point, com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] boundary) {
        boolean bool = false;
        if (AreaBoundaryUtil.isPointInPolygon(point, boundary)){
            bool = true;
        } else {//判断容差距离
            double minDis = Double.MAX_VALUE;
            for (int n = 0; n < boundary.length - 1; n++) {
                com.css.fxfzdzzh.modules.spatialData.repository.entity.Point p1 = boundary[n], p2 = boundary[n + 1];
                double d = AreaBoundaryUtil.pointToLine(p1.x, p1.y, p2.x, p2.y, point.x, point.y);
                if (minDis > d) minDis = d;
            }
            if (minDis < GLOBAL_THRESH) {
                bool = true;
            }
        }

        return bool;
    }

    //获取POLYGON单面所在区域边界列表
    public static List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> getPolygonPointsListByString(String coordinate){
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries = new ArrayList<>();
        if (coordinate == null || "".equals(coordinate)) {
            System.out.println("无面数据");
        } else {
            coordinate = coordinate.substring(coordinate.indexOf("((") + 2, coordinate.lastIndexOf("))"));
            coordinate = coordinate.replace("), (", "#");
            String[] coordinates = StringUtils.split(coordinate, "#");
            for (int j = 0; j < coordinates.length; j++) {
                coordinates[j] = coordinates[j].replace(", ",";");
                coordinates[j] = coordinates[j].replace(" ",",");
                String[] lonlats = StringUtils.split(coordinates[j],";");
                com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] points = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[lonlats.length];
                for (int i = 0;i < lonlats.length;i++) {
                    String[] lonlat = StringUtils.split(lonlats[i], ",");
                    com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point();
                    point.x = Double.parseDouble(lonlat[0]);
                    point.y = Double.parseDouble(lonlat[1]);
                    points[i] = point;
                }
                boundaries.add(points);
            }
        }

        return boundaries;
    }

    //获取省市县所在区域边界列表
    public static List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> getDistrictBoundaryByString(String coordinate){
        List<com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[]> boundaries = new ArrayList<>();
        if (coordinate == null || "".equals(coordinate)) {
            System.out.println("NoDistrictBoundaryData");
        } else {
            coordinate = coordinate.substring(coordinate.indexOf("(((") + 3, coordinate.lastIndexOf(")))"));
            coordinate = coordinate.replace(")), ((", "|");
            //coordinate = coordinate.replace("), (", "#");
            coordinate = coordinate.replace("), (", "|");
            String[] coordinates = StringUtils.split(coordinate, "|");
            for (int j = 0; j < coordinates.length; j++) {
                coordinates[j] = coordinates[j].replace(", ",";");
                coordinates[j] = coordinates[j].replace(" ",",");
                String[] lonlats = StringUtils.split(coordinates[j],";");
                com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[] points = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point[lonlats.length];
                for (int i = 0;i < lonlats.length;i++) {
                    String[] lonlat = StringUtils.split(lonlats[i], ",");
                    com.css.fxfzdzzh.modules.spatialData.repository.entity.Point point = new com.css.fxfzdzzh.modules.spatialData.repository.entity.Point();
                    point.x = Double.parseDouble(lonlat[0]);
                    point.y = Double.parseDouble(lonlat[1]);
                    points[i] = point;
                }
                boundaries.add(points);
            }
        }

        return boundaries;
    }
}
